﻿//ChartHelper.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Xaml
{
	using System;
	using System.Collections.Generic;
	using System.Drawing.Imaging;
	using System.IO;
	using System.Linq;
	using System.Windows.Media;

	using Ecng.Common;
	using Ecng.Serialization;

	using StockSharp.Algo.Candles;

	/// <summary>
	/// Вспомогательный класс для работы с <see cref="Chart"/>.
	/// </summary>
	public static class ChartHelper
	{
		private static int _counter;

		/// <summary>
		/// Получить уникальное имя для серии.
		/// </summary>
		/// <param name="prefix">Префикс имени.</param>
		/// <returns>Уникальное имя.</returns>
		public static string SeriesName(this string prefix)
		{
			return prefix + "Series" + _counter++;
		}

		/// <summary>
		/// Перевести время в формате графика.
		/// </summary>
		/// <param name="time">Время.</param>
		/// <returns>Время в формате графика.</returns>
		public static double ToChartTime(this DateTime time)
		{
			return time.ToOADate();
		}

		internal static SettingsStorage ToStorage(this Color color)
		{
			var storage = new SettingsStorage();

			storage.SetValue("A", color.A);
			storage.SetValue("R", color.R);
			storage.SetValue("G", color.G);
			storage.SetValue("B", color.B);

			return storage;
		}

		internal static Color ToColor(this SettingsStorage settings)
		{
			if (settings == null)
				throw new ArgumentNullException("settings");

			return Color.FromArgb(settings.GetValue<byte>("A"), settings.GetValue<byte>("R"), settings.GetValue<byte>("G"), settings.GetValue<byte>("B"));
		}

		/// <summary>
		/// Обработать свечку.
		/// </summary>
		/// <param name="chart">График.</param>
		/// <param name="candleElement">Элемент графика, представляющий свечки.</param>
		/// <param name="candle">Свечка.</param>
		public static void ProcessCandle(this IChart chart, ChartCandleElement candleElement, Candle candle)
		{
			if (candleElement == null)
				throw new ArgumentNullException("candleElement");

			if (candle == null)
				throw new ArgumentNullException("candle");

			chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object> { { candleElement, candle } });
		}

		/// <summary>
		/// Обработать новые данные.
		/// </summary>
		/// <param name="chart">График.</param>
		/// <param name="time">Временная отметка формирования новых данных.</param>
		/// <param name="values">Новые данные.</param>
		public static void ProcessValues(this IChart chart, DateTime time, IDictionary<IChartElement, object> values)
		{
			if (chart == null)
				throw new ArgumentNullException("chart");

			chart.ProcessValues(new Dictionary<DateTime, IDictionary<IChartElement, object>> { { time, values } });
		}

		/// <summary>
		/// Сохранить данные графика в текстовый файл.
		/// </summary>
		/// <param name="chart">График.</param>
		public static void SaveToTxt(this Chart chart)
		{
			if (chart == null)
				throw new ArgumentNullException("chart");

			foreach (var series in chart.MsChart.Series)
			{
				File.WriteAllLines(series.Name + ".txt",
					series
						.Points
						.Select(p => "{0} {1}".Put(
							DateTime.FromOADate(p.XValue),
							p.YValues.Select(v => v.ToString()).Join(", "))));
			}
		}

		/// <summary>
		/// Сохранить график в изображение.
		/// </summary>
		/// <param name="chart">График.</param>
		/// <param name="fileName">Название файла.</param>
		/// <param name="format">Формат изображения.</param>
		public static void SaveToImage(this Chart chart, string fileName, ImageFormat format)
		{
			if (chart == null)
				throw new ArgumentNullException("chart");

			if (fileName.IsEmpty())
				throw new ArgumentNullException("fileName");

			chart.MsChart.SaveImage(fileName, format);
		}

		/// <summary>
		/// Вернуть область по указанному индексу. Если областей меньше, то недостающие будут созданы автоматически.
		/// </summary>
		/// <param name="chart">График.</param>
		/// <param name="index">Индекс области.</param>
		/// <returns>Область.</returns>
		public static ChartArea GetArea(this Chart chart, int index)
		{
			if (chart == null)
				throw new ArgumentNullException("chart");

			if (index < 0)
				throw new ArgumentOutOfRangeException("index");

			while (chart.Areas.Count < index + 1)
			{
				var area = new ChartArea { Title = "Панель " + index };
				chart.Areas.Add(area);
			}

			return chart.Areas[index];
		}
	}
}